#pragma once
#include "routing_table.h"
#include "socket.h"
#include "task.h"
#include <cerrno>
#include <cstddef>
#include <cstring>
#include <functional>
#include <netinet/in.h>
#include <span>
#include <string>
#include <strings.h>
#include <sys/epoll.h>
#include <sys/socket.h>

using namespace std::chrono_literals;

namespace cobt {

std::string sockaddr_to_string(const SocketAddress &addr);

void sendto(int fd, std::span<char> buf, const SocketAddress &addr, int flags);

Task<>
recvfrom_async(int fd, int flags,
               std::function<void(std::span<char>, const SocketAddress &)> cb);


constexpr size_t COBT_SINGLE_MAX_CONNECTIONS = 4;


void ping(int fd, const SocketAddress &addr, const std::string &id);
void find_node(int fd, const SocketAddress &addr, const std::string &id,
               const std::string &target);
void get_peers(int fd, const SocketAddress &addr, const std::string &id,
               const std::string &info_hash);

std::optional<DHTNode> parse_compact(const std::string &compact);
std::optional<SocketAddress> parse_compact_addr(const std::string &compact);

} // namespace cobt